---
order: 4.143
category: '@threlte/extras'
sourcePath: 'packages/extras/src/lib/components/environment/VirtualEnvironment/VirtualEnvironment.svelte'
title: <VirtualEnvironment>
type: 'component'
componentSignature:
  {
    exports:
      [
        { name: 'restart', type: '() => void', description: 'Restarts the update task' },
        {
          name: 'update',
          type: '() => void',
          description: 'Causes the cube camera to render to its render target'
        }
      ],
    props:
      [
        {
          default: '0.1',
          description: 'The near plane of the cube camera',
          name: 'near',
          required: false,
          type: 'number'
        },
        {
          default: '1000',
          description: 'The far plane of the cube camera',
          name: 'far',
          required: false,
          type: 'number'
        },
        {
          default: 'Infinity',
          description: 'Determines how many frames the internal task will run for',
          name: 'frames',
          required: false,
          type: 'number'
        },
        {
          description: 'Callback that is ran when the internal update task is started',
          name: 'onupdatestart',
          required: false,
          type: '() => void'
        },
        {
          description: 'Callback that is ran when the internal update task is stopped',
          name: 'onupdatestop',
          required: false,
          type: '() => void'
        },
        {
          default: '256',
          description: 'The width and height of the cube cameras render target',
          name: 'resolution',
          required: false,
          type: 'number'
        },
        {
          default: 'false',
          description: 'Whether to set `scene.background` to the environment texture',
          name: 'isBackground',
          required: false,
          type: 'boolean'
        },
        {
          default: 'useThrelte().scene',
          description: 'The scene that will have its environment and/or background set',
          name: 'scene',
          required: false,
          type: 'THREE.Scene'
        },
        {
          default: 'false',
          description: 'Whether to render the virtual environment into the scene',
          name: 'visible',
          required: false,
          type: 'boolean'
        }
      ]
  }
---

<Example path="extras/virtual-environment/basic" />

`<VirtualEnvironment>` allows you to create dynamic environment maps which can
be used to light your scene and adjust reflections on your scene's objects.

It uses a cube camera to create a cubemap of its contents and applies that
cubemap texture to the scene's environment. `<VirtualEnvironment>` internally
creates a new scene to render the virtual environment into. The contents of
`<VirtualEnvironment>` may be mounted and made visible by setting the `visible`
prop to `true`.

## Controlling Updates

By default, the cube camera updates and renders to its render target every
frame. The `frames` prop is used to control the amount of updates that occur. If
your virtual scene is static, you may only need the cube camera to update once.
You can achieve this by settings `frames` to `1`:

```svelte
<VirtualEnvironment frames={1} />
```

This will cause the cube camera to update once and then stop its update task. If
you ever need to restart the task, a `restart` function is available as a
component export and through the `children` snippet.

```svelte title="As-A-Component-Export"
<script>
  let virtualEnvironment = $state()

  $effect(() => {
    // yourDependencyHere
    virtualEnvironment?.restart()
  })
</script>

<VirtualEnvironment
  frames={1}
  bind:this={virtualEnvironment}
/>
```

```svelte title="Through-Children-Snippet"
<script>
  let meshInScene = $state(true)
</script>

<VirtualEnvironment
  frames={1}
  bind:this={virtualEnvironment}
>
  {#snippet children({ restart })}
    {#if meshInScene}
      <T.Mesh>
        <T.PlaneGeometry />
      </T.Mesh>
    {/if}
  {/snippet}
</VirtualEnvironment>
```

### Manual Updates

For cases where you want full control over when the render target is updated,
use the `update` function available as a component export and through the
`children` snippet.

<Tip type="warning">
  If you use the `update` function, be sure to set `frames` to `0` to prevent the internal update
  task from starting automatically.
</Tip>

#### As a Component Export

```svelte title="Scene.svelte"
<script>
  let virtualEnvironment = $state()
  $effect(() => {
    // …
    virtualEnvironment?.update()
  })
</script>

<VirtualEnvironment
  frames={0}
  bind:this={virtualEnvironment}
>
  <!-- Your scene contents here -->
</VirtualEnvironment>
```

#### Through Children Snippet

```svelte title="Scene.svelte"
<VirtualEnvironment frames={0}>
  {#snippet children({ update })}
    <T.Mesh
      oncreate={() => {
        update()
      }}
    >
      <T.PlaneGeometry />
    </T.Mesh>
  {/snippet}
</VirtualEnvironment>
```

The example below is the same as the one above but it only updates the cube
camera's render target when the light formers are updated instead of every
frame.

<Example path="extras/virtual-environment/manual-updates" />

## Mixing Virtual and Real Environments

You can also mix `<VirtualEnvironment>` with `<Environment>` or
`<CubeEnvironment>` to create a mix of "real" and virtual environments.

```svelte title="Scene.svelte"
<VirtualEnvironment>
  <Environment
    url="…"
    isBackground
  />

  <T.Mesh>
    <T.PlaneGeometry />
  </T.Mesh>
</VirtualEnvironment>
```

<Example path="extras/virtual-environment/mix" />
